package com.hmdp.utils;

import com.hmdp.service.impl.ShopServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

@Component
public class RedisIdWorker {

    /*生成2022年1月1日定义的秒数*/
    private static final long BEGIN_TIMESTAMP=1640995200L;

    /*长度，这里记录的是下面count的长度*/
    private static final int COUNT_BITS=32;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /*
    * 这个方法用于生成全局唯一id
    * 该id由64位组成，0/1是符号位，紧接着的31位是timestamp，也就是时间搓
    * 后面的32位是count，也就是序列号；两者结合起来会生成一个全局唯一id
    * count又作为redis里面的自增value,其对应的key根据日期在每天变化
    * 因此也可以根据key查询到的value得到当天自增的数值
    * */
    public long nextId(String keyPrefix){
        /*1.生成时间戳*/
        /*当前时间减去初始时间*/
        LocalDateTime now=LocalDateTime.now();
        /*得到当前的秒数*/
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp=nowSecond- BEGIN_TIMESTAMP;

        /*2.生成序列号*/
        /*调用redis里面的string类型进行数据自增*/
        /*这里的序列号的key设置成每天一个key,不同天设置不同的key*/
        String yyyyMMdd = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        long count = stringRedisTemplate.opsForValue().increment(RedisConstants.REDISE_ICR + keyPrefix + ":" + yyyyMMdd);

        /*3.拼接并返回*/
        /*这里将时间搓和count进行拼接，时间搓放在前面，count放在后面，用位运算和或运算实现拼接*/
        return timestamp<<COUNT_BITS | count;
    }

    public static void main(String[] args) {
        /*生成2022年1月1日定义的秒数*/
        LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0);
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println("second="+second);
    }

}









